package br.com.musclebook.error;

import java.util.Iterator;

import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.application.NavigationHandler;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.servlet.http.HttpServletRequest;

import org.omnifaces.config.WebXml;
import org.omnifaces.exceptionhandler.FullAjaxExceptionHandler;
import org.omnifaces.util.Exceptions;

public class MuscleBookExceptionHandler extends FullAjaxExceptionHandler {

    public MuscleBookExceptionHandler(ExceptionHandler exceptionHandler) {
	super(exceptionHandler);
    }

    public void handle() throws FacesException {
	FacesContext fc = FacesContext.getCurrentInstance();

	if (fc.getPartialViewContext().isAjaxRequest()) { // Ajax requests handled by superclass...
	    super.handle();
	} else {
	    Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();

	    while (i.hasNext()) {
		ExceptionQueuedEvent event = i.next();

		try {
		    Throwable exception = Exceptions.unwrap(event.getContext().getException()); // get rid of FacesExceptions

		    if (exception instanceof MusclebookException) { // handle specific MusclebookExceptions
			MusclebookException muscleBookException = (MusclebookException) exception;
			if (muscleBookException != null) {
			    fc.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, muscleBookException.getMessage(), muscleBookException.getMessage()));
			    return;
			}
		    }
		    
		    HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
		    request.setAttribute("javax.servlet.error.exception", exception);

		    NavigationHandler nav = fc.getApplication().getNavigationHandler();
		    nav.handleNavigation(fc, null, WebXml.INSTANCE.findErrorPageLocation(exception));
		    fc.renderResponse();
		} finally {
		    i.remove();
		}
	    }

	    super.getWrapped().handle();
	}
    }

}
